package com.nt.thah.service.impl;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nt.thah.constant.SysCode;
import com.nt.thah.constant.WebConfig;
import com.nt.thah.dao.*;
import com.nt.thah.entity.*;
import com.nt.thah.exception.BusinessException;
import com.nt.thah.service.CommonService;
import com.nt.thah.utils.MapUtils;
import com.nt.thah.utils.NumberUtils;
import com.nt.thah.utils.RedisUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description: 商机信息Service
 * @author: ls
 * @Date: 2020-07-14 15:55:36
 */
@Slf4j
@Service
public class CommonServiceImpl implements CommonService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private UserDao userDao;

    @Resource
    private ScoreDetailDao scoreDetailDao;

    @Resource
    private ScoreAccountDao scoreAccountDao;

    @Resource
    private CarbonAccountDao carbonAccountDao;

    @Resource
    private WebConfig webConfig;

    @Resource
    private ProductDao productDao;

    @Resource
    private ProductAttrDao productAttrDao;

    @Resource
    private CarbonDetailDao carbonDetailDao;

    /**
     * @Description: 删除用户缓存信息
     * @author: ls
     * @Date: 2020/7/21 20:34
     */
    public void delUserCache(Integer userId) {
        String redisKey = String.format("%s%s", SysCode.REDIS_KEY_USER_INFO, userId);
        redisUtil.del(redisKey);
    }

    /**
     * @Description: 获取账户信息
     * @author: ls
     * @Date: 2020/7/21 20:34
     */
    @Override
    public ScoreAccount getScoreAccount(Integer userId) {
        String redisKey = String.format("%s%s", SysCode.REDIS_KEY_ACCOUNT_INFO, userId);
        String userStr = redisUtil.get(redisKey);
        if (StringUtils.isNotBlank(userStr)) {
            return JSON.parseObject(userStr, ScoreAccount.class);
        }
        ScoreAccount ua = scoreAccountDao.getAccountById(userId);
        if (ua == null) {
            return null;
        }
        int random = NumberUtils.getRandom(1, 7);
        redisUtil.set(redisKey, JSON.toJSONString(ua), random, TimeUnit.DAYS);
        return ua;
    }

    /**
     * @Description: 获取用户信息
     * @author: ls
     * @Date: 2020/7/21 20:34
     */
    @Override
    public User getUserInfo(Integer userId) {
        String redisKey = String.format("%s%s", SysCode.REDIS_KEY_USER_INFO, userId);
        String userStr = redisUtil.get(redisKey);
        if (StringUtils.isNotBlank(userStr)) {
            return JSON.parseObject(userStr, User.class);
        }
        User user = userDao.getUserById(userId);
        if (StringUtils.isBlank(user.getHeadImg())) {
            user.setHeadImg("https://oss.tanhuiah.com/system/head.png");
        } else {
            user.setHeadImg(webConfig.getMyOssDomainName() + user.getHeadImg());
        }
        if (StringUtils.isBlank(user.getName())) {
            user.setName("低碳用户");
        }
        int random = NumberUtils.getRandom(1, 7);
        redisUtil.set(redisKey, JSON.toJSONString(user), random, TimeUnit.DAYS);
        return user;
    }

    /**
     * @Description: 构建查询方法的公共返回结果
     * @Author: ls
     * @Date: 2020/08/13 11:09
     */
    @Override
    public <T> Map<String, Object> buildQryResultMap(List<T> beanList) {
        Map<String, Object> resultMap = Maps.newHashMapWithExpectedSize(2);
        PageInfo<T> pageInfo = PageInfo.of(beanList);
        resultMap.put("list", beanList);
        resultMap.put("totalNum", pageInfo.getTotal());
        resultMap.put("pages", pageInfo.getPages());
        return resultMap;
    }

    /**
     * @Description: 保存积分信息
     * @Author ls
     * @Date 2021/08/26 16:53
     */
    @Override
    public void saveScore(Integer userId, Integer score, Integer type) {
        // 1、保存积分明细
        ScoreDetail sd = ScoreDetail.builder().userId(userId).score(score).type(type).build();
        scoreDetailDao.save(sd);
        // 2、更新账户信息
        ScoreAccount sa = ScoreAccount.builder().userId(userId).balance(Long.valueOf(score)).total(Long.valueOf(score)).build();
        Integer id = scoreAccountDao.checkIsExist(userId);
        if (id == null) {
            scoreAccountDao.save(sa);
        } else {
            sa.setId(id);
            scoreAccountDao.update(sa);
        }
        String redisKey = String.format("%s%s", SysCode.REDIS_KEY_ACCOUNT_INFO, userId);
        redisUtil.del(redisKey);
        // 3、更新用户等级
        ScoreAccount sa1 = getScoreAccount(userId);
        Integer level = getLevel(sa1.getTotal());
        User user = User.builder().id(userId).level(level).build();
        userDao.updateUserById(user);
        delUserCache(userId);
    }

    /**
     * @Description: 保存减碳量信息
     * @Author ls
     * @Date 2021/08/26 16:53
     */
    @Override
    public void saveCarbon(Integer userId, Integer carbonReduce, Integer type) {
        // 1、保存明细
        CarbonDetail cd = CarbonDetail.builder().userId(userId).carbon(carbonReduce).type(type).build();
        carbonDetailDao.save(cd);
        // 2、更新碳账户信息
        CarbonAccount ca = CarbonAccount.builder().userId(userId).total(Long.valueOf(carbonReduce)).build();
        Integer id = carbonAccountDao.checkIsExist(userId);
        if (id == null) {
            carbonAccountDao.save(ca);
        } else {
            ca.setId(id);
            carbonAccountDao.update(ca);
        }
        String redisKey = String.format("%s%s", SysCode.REDIS_KEY_CARBON_INFO, userId);
        redisUtil.del(redisKey);
    }

    /**
     * @Description: 获取碳账户信息
     * @Author: ls
     * @Date: 2020/08/03 0:30
     */
    @Override
    public CarbonAccount getCarbonAccount(Integer userId) {
        String redisKey = String.format("%s%s", SysCode.REDIS_KEY_CARBON_INFO, userId);
        String userStr = redisUtil.get(redisKey);
        if (StringUtils.isNotBlank(userStr)) {
            return JSON.parseObject(userStr, CarbonAccount.class);
        }
        CarbonAccount cb = carbonAccountDao.getAccount(userId);
        if (cb == null) {
            return null;
        }
        int random = NumberUtils.getRandom(1, 7);
        redisUtil.set(redisKey, JSON.toJSONString(cb), random, TimeUnit.DAYS);
        return cb;
    }

    /**
     * @Description: 获取产品详情
     * @Author: ls
     * @Date: 2020/08/03 0:30
     */
    @Override
    public JSONObject getProductInfo(Integer productId) {
        JSONObject jsonObject = new JSONObject();
        Product product = productDao.getProductById(productId);
        try {
            Map<String, Object> productMap = MapUtils.convertBean2Map(product);
            jsonObject.putAll(productMap);
        } catch (Exception e) {
            log.error("查询产品详情出错,{}", e.getMessage());
        }
        List<ProductAttr> attrList = productAttrDao.getList(productId);
        if (CollectionUtils.isEmpty(attrList)) {
            return jsonObject;
        }
        Map<String, String> collect = attrList.stream().collect(Collectors.toMap(ProductAttr::getKey, ProductAttr::getValue));
        jsonObject.putAll(collect);
        jsonObject.put("detail", StringUtils.split(jsonObject.getString("detail"), "|"));
        return jsonObject;
    }

    /**
     * @Description: 获取积分所在等级
     * @Author: ls
     * @Date: 2020/08/03 0:30
     */
    private Integer getLevel(Long total) {
        int level;
        if (total > 15 && total < 200) {
            level = 1;
        } else if (total >= 200 && total < 800) {
            level = 2;
        } else if (total >= 800 && total < 2000) {
            level = 3;
        } else if (total >= 2000 && total < 5000) {
            level = 4;
        } else if (total >= 5000) {
            level = 5;
        } else {
            level = 1;
        }
        return level;
    }

    /**
     * @Description: 分页
     * @Author: ls
     * @Date: 2020/08/03 0:30
     */
    @Override
    public <T> List<T> getPageList(List<T> dataList, Integer pageNum, Integer pageSize) {
        List<T> currentPageList = Lists.newArrayList();
        if (dataList != null && dataList.size() > 0) {
            int currIdx = (pageNum != null && pageNum > 1) ? (pageNum - 1) * pageSize : 0;
            for (int i = 0; i < pageSize && i < dataList.size() - currIdx; i++) {
                T data = dataList.get(currIdx + i);
                currentPageList.add(data);
            }
        }
        return currentPageList;
    }

}